package com.iteaj.iot.serial;

import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortEvent;
import com.fazecast.jSerialComm.SerialPortMessageListener;
import com.fazecast.jSerialComm.SerialPortMessageListenerWithExceptions;
import com.iteaj.iot.ProtocolHandle;

public class SerialPortDelimiterListener implements SerialPortMessageListener, SerialPortMessageListenerWithExceptions {

    private byte[] delimiter;
    private SerialEventProtocol eventProtocol;
    private SerialConnectProperties properties;
    private boolean delimiterIndicatesEndOfMessage;
    private ProtocolHandle<SerialEventProtocol> handle;

    public SerialPortDelimiterListener(byte[] delimiter, SerialConnectProperties properties, SerialEventProtocolHandle handle, boolean endOfMessage) {
        this.handle = handle;
        this.delimiter = delimiter;
        this.properties = properties;
        this.delimiterIndicatesEndOfMessage = endOfMessage;
        this.eventProtocol = new SerialEventProtocol(null, properties);
    }

    @Override
    public byte[] getMessageDelimiter() {
        return this.delimiter;
    }

    @Override
    public boolean delimiterIndicatesEndOfMessage() {
        return this.delimiterIndicatesEndOfMessage;
    }

    @Override
    public int getListeningEvents() {
        return SerialPort.LISTENING_EVENT_DATA_RECEIVED
                | SerialPort.LISTENING_EVENT_DATA_WRITTEN
                | SerialPort.LISTENING_EVENT_DATA_AVAILABLE
                | SerialPort.LISTENING_EVENT_PORT_DISCONNECTED;
    }

    @Override
    public void serialEvent(SerialPortEvent event) {
        this.handle.handle(this.eventProtocol.setEvent(event));
    }

    @Override
    public void catchException(Exception e) {
        this.handle.handle(this.eventProtocol);
    }

    public SerialPortDelimiterListener setDelimiterIndicatesEndOfMessage(boolean delimiterIndicatesEndOfMessage) {
        this.delimiterIndicatesEndOfMessage = delimiterIndicatesEndOfMessage; return this;
    }
}
